package com.example.movie.data.user.login.model

import android.os.Handler
import android.os.Looper
import android.os.Message
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import cn.forward.androids.utils.ThreadUtil
import com.example.movie.R
import com.example.movie.common.constants.AppConstants.PHONE
import com.example.movie.common.constants.LoadingState
import com.example.movie.common.model.RequestResult
import com.example.movie.common.model.Result
import com.example.movie.data.user.model.UserRepository

class SharedLoginViewModel(private val loginRepository: UserRepository) : ViewModel() {

    private val _loginForm = MutableLiveData<LoginFormState>()
    val loginFormState: LiveData<LoginFormState>
        get() = _loginForm

    /**
     * 登陆状态
     */
    private val _loginResult = MediatorLiveData<RequestResult<LoggedInUserView>>()
    val loginResult: MediatorLiveData<RequestResult<LoggedInUserView>>
        get() = _loginResult

    /**
     * 注册状态
     */
    private val _registerResult = MutableLiveData<RequestResult<Any>>()
    val registerResult: MutableLiveData<RequestResult<Any>>
        get() = _registerResult

    /**
     * 注销状态
     */
    private val _logoutResult = MutableLiveData<RequestResult<Any>>()
    val logoutResult: MutableLiveData<RequestResult<Any>>
        get() = _logoutResult


    /**
     * 判断用户是否登陆
     */
    fun isLoggedIn(): Boolean {
        _loginResult.value?.success?.let {
            return true
        }
        return false
    }

    /**
     * 用户登陆
     */
    fun login(
        username: String,
        password: String
    ) {
        // can be launched in a separate asynchronous job
        var result: Result<LoggedInUser>? = null;
        val handler = object : Handler(Looper.myLooper()!!) {
            override fun handleMessage(msg: Message) {
                if (msg.what == LoadingState.OK) {
                    if (result is Result.Success) {
                        _loginResult.value =
                            RequestResult(
                                success = LoggedInUserView(
                                    nickName = (result as Result.Success<LoggedInUser>).data?.userName,
                                    headImg = (result as Result.Success<LoggedInUser>).data?.headImg,
                                    hopeLook = (result as Result.Success<LoggedInUser>).data?.hopeLook,
                                    hasSee = (result as Result.Success<LoggedInUser>).data?.hasSeen,
                                    sign = (result as Result.Success<LoggedInUser>).data?.sign,
                                    phoneNumber = (result as Result.Success<LoggedInUser>).data?.mobile
                                )
                            )
                        clearLogoutResult()
                    } else {
                        _loginResult.value = RequestResult(error = R.string.login_failed)
                    }
                }
            }

        }

        ThreadUtil.getInstance().execute {
            result = loginRepository.login(username, password)
            //登录线程数据请求完成
            val message = Message()
            message.what = LoadingState.OK
            handler.sendMessage(message)
        }

    }

    fun loginDataChanged(username: String, password: String) {
        var dataValid = true
        if (isUserNameNotValid(username)) {
            _loginForm.value = LoginFormState(usernameError = R.string.invalid_username)
            dataValid = false
        }
        if (isPasswordNotValid(password)) {
            _loginForm.value = LoginFormState(passwordError = R.string.invalid_password)
            dataValid = false
        }
        if (dataValid && username.isNotEmpty() && password.isNotEmpty()) {
            _loginForm.value = LoginFormState(isDataValid = true)
        }
    }

    // A placeholder username validation check
    private fun isUserNameNotValid(username: String): Boolean {
        return username.isNotEmpty() && !username.matches(Regex(PHONE))
    }

    // A placeholder password validation check
    private fun isPasswordNotValid(password: String): Boolean {
        return password.isNotEmpty() && password.length <= 5
    }

    /**
     * 用户注册
     */
    fun register(username: String, password: String) {
        var result: Result<Any>? = null;
        val handler = object : Handler(Looper.myLooper()!!) {
            override fun handleMessage(msg: Message) {
                if (msg.what == LoadingState.OK) {
                    if (result is Result.Success) {
                        _registerResult.value =
                            RequestResult(success = (result as Result.Success<Any>).data)
                    } else {
                        _registerResult.value = RequestResult(error = R.string.register_failed)
                    }
                }
            }
        }

        ThreadUtil.getInstance().execute {
            result = loginRepository.register(username, password)
            val message = Message()
            message.what = LoadingState.OK
            handler.sendMessage(message)
        }
    }

    fun logout() {
        var result: Result<Any>? = null;
        val handler = object : Handler(Looper.myLooper()!!) {
            override fun handleMessage(msg: Message) {
                if (msg.what == LoadingState.OK) {
                    if (result is Result.Success) {
                        _logoutResult.value =
                            RequestResult(success = (result as Result.Success<Any>).data)
                        clearLoggedInUserData()
                    } else {
                        _logoutResult.value = RequestResult(error = R.string.logout_failed)
                    }
                }
            }
        }

        ThreadUtil.getInstance().execute {
            result = loginRepository.logout()
            val message = Message()
            message.what = LoadingState.OK
            handler.sendMessage(message)
        }
    }

    fun clearLoggedInUserData() {
        _loginResult.value = null
    }

    fun clearLogoutResult() {
        _logoutResult.value = null
    }

}